﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FantastPlatform.Framework.IService;
using FantastPlatform.Framework.IModel;
using FantastPlatform.Framework.Model;
using NHibernate;
using NHibernate.Criterion;
using FantastPlatform.Framework.Exception;
using FantastPlatform.Framework.Common;

namespace FantastPlatform.Framework.Service
{
    internal class OrganizationService : NodeService<IOrganization, Organization>, IOrganizationService
    {

        #region IOrganizationService 成员

        public IList<IPosition> LoadPositionNotExist(int organizationId, string keywords, int pageSize, int page, out int totalCount)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(Position)).Add(Expression.Eq("Enable", true)).
                Add(Expression.Sql(string.Format("not exists(select * from Org_Post where PositionId=this_.Id and OrganizationId={0})", organizationId)));
            if (string.IsNullOrEmpty(keywords))
                criteria.Add(Expression.Like("Name", keywords, MatchMode.Anywhere));
            ICriteria clone = criteria.Clone() as ICriteria;
            totalCount = int.Parse(clone.SetProjection(Projections.RowCount()).UniqueResult().ToString());
            return criteria.SetFirstResult((page - 1) * pageSize).SetMaxResults(pageSize).List<IPosition>();
        }

        #endregion

        public override void Delete(int id)
        {
            ITransaction transaction = null;
            ExecuteTransaction((ITransaction tan) =>
            {
                IOrganization entity = Session.Get<Organization>(id) as IOrganization;
                if (entity != null)
                    Check.Require<InvalidCodeException>(!IsUsing(entity), "当前组织机构正在被使用不能删除！");
                Session.Delete(entity);
            }, transaction);
        }
        public override void Delete(List<int> ids)
        {
            ITransaction transaction = null;
            ExecuteTransaction((ITransaction tan) =>
            {
                foreach (int id in ids)
                {
                    IOrganization entity = Session.Get<Organization>(id) as IOrganization;
                    if (entity != null)
                        Check.Require<InvalidCodeException>(!IsUsing(entity), "当前组织机构正在被使用不能删除！");
                    Session.Delete(entity);
                }
            }, transaction);
        }

        #region IOrganizationService 成员
        public IList<IOrganization> LoadExceptChildrenOrganizations(int organizationId)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(Organization)).Add(Expression.Eq("Enable", true))
                .Add(Expression.Not(Expression.Eq("Parent.Id", organizationId)));
            IList<IOrganization> list = criteria.List<IOrganization>();
            return list;
        }    
        public IList<IEmployee> LoadEmployeesByOrganizationId(int organizationId, int pageSize, int page, out int totalCount)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(Employee)).Add(Expression.Eq("Enable", true)).
                CreateAlias("EmployeePosts", "e").Add(Expression.Eq("e.Enable", true)).CreateAlias("e.Post", "p").Add(Expression.Eq("p.Organization.Id", organizationId));
            ICriteria clone = criteria.Clone() as ICriteria;
            totalCount = int.Parse(clone.SetProjection(Projections.RowCount()).UniqueResult().ToString());
            return criteria.SetFirstResult((page - 1) * pageSize).SetMaxResults(pageSize).List<IEmployee>();
        }
        
        public IList<IPost> LoadPostsByOrganizationId(int organizationId, int pageSize, int page, out int totalCount)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(Post)).Add(Expression.Eq("Enable", true)).Add(Expression.Eq("Organization.Id", organizationId));
            ICriteria clone = criteria.Clone() as ICriteria;
            totalCount = int.Parse(clone.SetProjection(Projections.RowCount()).UniqueResult().ToString());
            return criteria.SetFirstResult((page - 1) * pageSize).SetMaxResults(pageSize).List<IPost>();
        }

        #endregion


        public IOrganization GetOrganizationByName(string name)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(Organization)).Add(Expression.Eq("Enable", true))
                .Add(Expression.Eq("Name", name));
            IOrganization org = criteria.List<IOrganization>().SingleOrDefault();
            return org;
        }
    }
}
